﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;
using OpenLS.Spreadsheet.Formats.Biff.Records.Styling;

namespace OpenLS.Spreadsheet.Formats.Biff.Records
{
    internal class StyleExtRecord : BiffRecord
    {
        private BuiltInStyle _builtInData;
        private FrtHeader _frtHeader;
        private StyleCategory _iCategory;
        private LPWideString _stName;
        private XFProps _xfProps;
        private bool fBuiltIn;
        private bool fCustom;
        private bool fHidden;
        public byte? BuiltInId
        {
            get
            {
                if (fBuiltIn)
                    return _builtInData.BuildInId;
                return null;
            }
        }

        private byte Flags
        {
            get
            {
                byte result = 0;
                if (fBuiltIn)
                    result |= 0x01;
                if (fHidden)
                    result |= 0x02;
                if (fCustom)
                    result |= 0x04;
                return result;
            }
        }

        internal override BiffRecordType RecordType
        {
            get { return BiffRecordType.StyleExt; }
        }

        protected override void ReadContent(BiffReaderContext context, int length)
        {
            ReadReader(context.Reader);
        }

        private void ReadReader(BinaryReader reader)
        {
#if DEBUG
            ReadWriteChecker.CheckClass((t, r) => t.ReadReader(r), (t, w) => t.WriteWriter(w), reader, this);
#endif
            _frtHeader.Read(reader);
            Contract.Assert(_frtHeader._rt == 0x0892);
            byte flags = reader.ReadByte();
            fBuiltIn = (flags & 0x01) != 0;
            fHidden = (flags & 0x02) != 0;
            fCustom = (flags & 0x04) != 0;
            Contract.Assert(Flags == flags);
            _iCategory = (StyleCategory)reader.ReadByte();
            _builtInData.Read(reader);
            _stName.Read(reader);
            _xfProps.Read(reader);
        }

        public IEnumerable<XfProp> GetProps()
        {
            {
                return _xfProps.GetProps();
            }
        }

        internal override void WriteContent(BiffWriterWorkbookContext context)
        {
            WriteWriter(context.Writer);
        }

        private  void WriteWriter(BinaryWriter writer)
        {
            _frtHeader.Write(writer);
            Contract.Assert(_frtHeader._rt == 0x0892);
            writer.Write(Flags);
            writer.Write((byte)_iCategory);
            _builtInData.Write(writer);
            _stName.Write(writer);
            _xfProps.Write(writer);
        }

        #region Nested type: StyleCategory

        private enum StyleCategory : byte
        {
            Custom = 0,
            GoodBadNeutral = 1,
            DataModel = 2,
            TitleAndHeading = 3,
            ThemedCell = 4,
            NumberFormat = 5
        }

        #endregion

        public T GetPropertyValue<T>(XFPropDataBlobType arg) where T: XFPropValue
        {
            foreach (var v in GetProps())
                if (v.Type == arg)
                    return (T) v.Value;
            return null;

        }
    }
}